<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>PipeValid 2.0测试</title>
</head>
<body>

<!-- 不需要依赖jquery，不过在ie测试时，用到了$.Deferred -->
<script src="http://cdn.bootcss.com/jquery/1.8.3/jquery.js"></script>
<script src="../index-min.js"></script>
<!-- <script src="../src/util.js"></script>
<script src="../src/thenable.js"></script>
<script src="../src/checker.js"></script>
<script src="../src/item.js"></script>
<script src="../src/pipeValid.js"></script> -->
<script>
// 跑一个单元测试
var cc = [];

cc.push({
  desc: '正常声明',
  run: function(next) {
    var pipe = new PipeValid();
    next();
  }
});

cc.push({
  desc: '验证单个属性',
  run: function(next) {
    var pipe = new PipeValid();
    pipe.check('name')
      .min(3, '名字最少3位')
      .max(10, '名字最多10位');
    var result = pipe.start({
      name: 'da宗熊'
    });
    next(result.error);
  }
});

cc.push({
  desc: '验证单个属性，抛出错误的',
  run: function(next) {
    var pipe = new PipeValid();

    pipe.check('name')
      .min(10, '名字至少10个字');

    var result = pipe.start({ name: 'da宗熊' });

    next(result.error && result.error !== 'min' ? null : '应该抛出自定义的错误');
  }
});

cc.push({
  desc: '单个属性条件验证',
  run: function(next) {
    var pipe = new PipeValid();
    var nameChecker = pipe.check('name');

    nameChecker.min(10)
      .then()
      .max(5, '名字最大是5位，是不可能进入此验证的')
      .end()
      .max(10, '名字多大10位');

    var result = pipe.start({
      name: 'da宗熊'
    });

    next(result.error);
  }
});

cc.push({
  desc: '自定义验证函数',
  run: function(next) {
    PipeValid.define('noneBadword', function(val){
      return val.indexOf('bad') < 0;
    });

    var pipe = new PipeValid();
    pipe.check('word')
      .noneBadword('不能含有bad关键字');

    var result = pipe.start({
      word: 'I am a good word'
    });

    next(result.error);
  }
});

cc.push({
  desc: '自定义异步验证函数 + 异步返回结果',
  run: function(next) {
    var pipe = new PipeValid();

    pipe.define('ansyExistId', function(val) {
      var deferred = $.Deferred();
      setTimeout(function(){
        if (val.indexOf('x') === 0) {
          deferred.resolve();
        } else {
          deferred.reject();
        }
      }, 200);
      return deferred;
    });

    pipe.check('id')
      .ansyExistId('这个id不存在哦');

    // 检查含有异步，则需要通过 promise/a 规范，获取结果
    var result = pipe.start({ id: 'x9901' });

    result.always(function(){
      next(result.error);
    });
  }
});

cc.push({
  desc: '返回所有错误 + 验证简单的配置',
  run: function(next) {
    var pipe = new PipeValid();
    pipe.check({
      name: ['min', 5, '名字最少5位'],
      age: ['int', '年龄必须是整数'],
      address: [
        ['notEmpty'],
        ['then'],
        ['min', 10, '地址最短10位']
      ]
    });

    var isReturnAllError = true;
    var result = pipe.start({
      name: 'da宗熊',
      age: 'x11',
      address: '蟠龙街'
    }, isReturnAllError);

    next(result.error.length === 3 ? null : '需要返回3个错误');
  }
});

cc.push({
  desc: '指定验证某些属性 + 多个check链式调用',
  run: function(next) {
    var pipe = new PipeValid();

    pipe
      .check('name')
      .min(3, '名字最短3位')
      .check('age')
      .int('年龄必须是整形')
      .check('email')
      .email('邮箱格式不正确');

    var result = pipe.start({
      name: 'da宗熊',
      age: '22d',
      email: '1071093121@qq.com'
    }, ['name', 'email']);

    // 不验证 age 属性
    next(result.error);
  }
});

cc.push({
  desc: '验证属性表达式 + 量式自定义验证 + 抛出错误对象',
  run: function(next) {
    var pipe = new PipeValid();

    pipe
      .check('data.code')
        .int('返回码，需是整形')
      .check('list[].name')
        .notEmpty('列表名字不能为空')
        .min(3, '列表的各个名字，不得小于3位')
      .check('list[1].name')
        .define(function(val) {
          return val.indexOf('ch') !== 0;
        }, {
          code: 1,
          desc: '这是个被抛出的错误对象',
          error: '不能含有ch开头哦'
        });

    var result = pipe.start({
      data: {
        code: 0
      },
      list: [
        { name: 'da宗熊' },
        { name: 'ch小量' }
      ]
    });

    var error = result.error || {};
    if (error.code === 1) {
      next();
    } else {
      next('应该抛出list[1].name的错误!!');
    }
  }
});

cc.push({
  desc: '试验check().custom功能，此功能后面，可能会去除',
  run: function(next) {
    var pipe = new PipeValid();

    pipe.check('name')
      .custom(function(val, next) {
        if (this.notEmpty()) {
          // 如果附带错误，内置会自动调用 next
          this.min(3, '名字最少3位');
          this.max(10, '名字不能超过10位');

          var self = this;
          setTimeout(function() {
            if (val !== 'da宗熊') {
              next('名字必须是"da宗熊"');
            }
            next();
          }, 100);
        } else {
          next();
        }
      });

    var result = pipe.start({ name: 'da宗熊' });

    result.always(function(){
      next(result.error);
    });
  }
});

cc.push({
  desc: '验证所有内置验证器',
  run: function(next) {
    var pipe = new PipeValid();
    pipe
      .check('name')
        .notEmpty('请填入名字')
        .min(3, '名字至少3位数')
        .max(5, '名字不能超过5位数')
      .check('age')
        .notEmpty('请填入年龄')
        .gt(18, '年龄必须大于18')
        .lt(50, '年龄必须小于50')
      .check('money')
        .notEmpty()
      .then()
        .number('金币格式不正确1')
        .int('金币格式不正确2')
        .gte(100, '金钱必须超过或等于100')
        .lte(1000, '金钱必须小于或等于1000')
      .check('email')
        .notEmpty()
      .then()
        .email('邮箱格式不正确')
      .check('homepage')
        .notEmpty()
      .then()
        .url('个人主页地址不正确');

    var result = pipe.start({
      name: 'da宗熊',
      age: 20,
      money: '1000',
      email: 'test@qq.com',
      homepage: 'http://www.test.com/homepage.html',
    });
    
    next(result.error);
  }
});


var timeout = 5000;
var timer;
var index = 0;
function loopTest(cc) {
  var item = cc.shift();

  if (!item) {
    return logInfo('all success');
  }

  index++;
  var desc = item.desc || index;
  logInfo(index + '.' + desc);

  if (item.run) {
    var shouldStopRunner = false;

    clearTimeout(timer);
    timer = setTimeout(function(){
      shouldStopRunner = true;
      logError('  timeout');
    }, item.timeout || timeout);

    try {
      item.run(function(error) {
        clearTimeout(timer);
        if (shouldStopRunner) {
          return;
        }

        if (error) {
          logError('  ' + error);
        } else {
          logInfo('  pass');
          loopTest(cc);
        }
      });
    } catch (e) {
      clearTimeout(timer);
      logError('  ' + e.message);
      throw e;
    }
  }
}

var $logger;
function logForIE(text, color) {
  if (!$logger) {
    $logger = document.createElement('div');
    document.getElementsByTagName('body')[0].appendChild($logger);
  }
  $logger.innerHTML += '<div style="color:'+ color +'">'+ text +'</div>'
}

function logInfo(text) {
  if (window.console) {
    console.log('%c' + text, 'color:green');
  } else {
    logForIE(text, 'green');
  }
}

function logError(text) {
  if (window.console) {
    console.log('%c' + text, 'color:red');
  } else {
    logForIE(text, 'red');
  }
}

loopTest(cc);

</script>
</body>
</html>
